﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using MongoDB.Bson;
using MongoDB.Driver;

namespace MongoDAO.Repository
{
    public interface IRepository<T> where T : TDocument
    {
        T Insert(T obj);
        IEnumerable<T> InsertBatch(IEnumerable<T> objects);
        T Save(T obj);
        IEnumerable<T> FindAll();

        T FindOneById(object id);
        T FindOne(IMongoQuery query);
        T FindOne(Expression<Func<T, bool>> expression);

        IEnumerable<T> Find(IMongoQuery query);
        IEnumerable<T> Find(IMongoQuery query, int skip, int limit);

        IQueryable<T> Find(Expression<Func<T, bool>> expression);
        IEnumerable<T> Find(Expression<Func<T, bool>> expression, int skip, int limit);

        void Update(T obj);
        void Update(IMongoQuery query, IMongoUpdate updateBuilder);
        void UpdateById(object id, IMongoUpdate updateBuilder);

        T FindAndModifyById(object id, IMongoUpdate updateBuilder);



        void RemoveAll();
        void RemoveById(object id);
        void Remove(IMongoQuery query);
        long Count();
        long Count(IMongoQuery query);
        void EnsureIndex(IMongoIndexKeys keys);
        void EnsureIndex(IMongoIndexKeys keys, IMongoIndexOptions options);
        GetIndexesResult GetIndexes();

        //[Obsolete]
        //void Update(T obj, IMongoUpdate updateBuilder);
        //[Obsolete]
        //void Update(T obj, Expression<Func<T, object>> memberExpression, Operator mongoOperator, object value);
        //[Obsolete]
        //void Update(Expression<Func<T, bool>> expression, Expression<Func<T, object>> memberExpression, Operator mongoOperator, object value);
        //[Obsolete]
        //void Push(Expression<Func<T, bool>> expression, Expression<Func<T, IEnumerable<object>>> memberExpression, object obj);
        //[Obsolete]
        //void Pull(Expression<Func<T, bool>> expression, Expression<Func<T, IEnumerable<object>>> memberExpression, object obj);
        //[Obsolete]
        //void AddToSet(Expression<Func<T, bool>> expression, Expression<Func<T, IEnumerable<object>>> memberExpression, object obj);
        //[Obsolete]
        //void AddToSetEach(Expression<Func<T, bool>> expressionExpression, Expression<Func<T, IEnumerable<object>>> memberExpression, IEnumerable<object> objects);

    }
}
